Computer applications often call methods to perform an operation outside of the main process. Examples include accessing a resource, offloading an compute-intensive calculation, and reading files from storage. Generally, the approaches used to perform the methods include synchronous operations and asynchronous operations. Synchronous operations generally stall execution of main application while the method performs the task. Stalling the application runs the risk of holding onto valuable computing resources while the synchronous operation completes. The main application is resumed after the method returns a result. Asynchronous operations, in contrast, allow the application to continue to perform work while the method performs the task. Asynchronous operations are typically preferred over synchronous operations whenever the application calls a method that will wait a non-deterministically and relatively long time, such as accessing resources on a computer network. Further, research has demonstrated that asynchronous operations provide superior memory usage and throughput over synchronous operations.
Despite the advantages of using asynchronous operations, developers often prefer to use synchronous programming models to asynchronous programming models. Developers have found asynchronous programming models to be difficult to understand and implement as compared to the commonly used and relatively straightforward synchronous programming model. Traditionally, asynchronous programming in modern programming languages was implemented with callbacks. Recent advancements in language design have enabled asynchronous programming models to use the same sequential control flow constructs of synchronous code. But even with improvements in asynchronous program support, many capabilities of synchronous programming mechanisms remain unavailable in asynchronous programming.